Некоторые полезные исходники, которые могут быть полезны и вам.


#define keyLen 8
class A5Cripto{
  char *orStr,*crStr;
  typedef struct {unsigned long r1,r2,r3; } a5_ctx;
  a5_ctx  c;
  static int threshold(unsigned int r1, unsigned int r2, unsigned int r3);
  unsigned long clock_r1(int ctl, unsigned long r1);
  unsigned long clock_r2(int ctl, unsigned long r2);
  unsigned long clock_r3(int ctl,unsigned long  r3);
  int keystream(unsigned char *key, unsigned long frame, unsigned char *alice, unsigned char *bob);
  void a5_key(a5_ctx *c, char *k);
  int a5_step(a5_ctx *c);
  void a5_encrypt(a5_ctx *c, char *data, int len);
  void a5_decrypt(a5_ctx *c, char *data, int len);
  int len;
  unsigned char key[keyLen];
  void move(char*,char*);
public:
  A5Cripto::A5Cripto(){
    orStr=NULL;
    crStr=NULL;
  }
  A5Cripto::~A5Cripto(){
    if(orStr)delete orStr;
    if(crStr)delete crStr;
  }
  int getLenStr(){
    return len;
  }
  const char* getOrStr(){
   return orStr;
  }
  const char* getCrStr(){
   return crStr;
  }
  bool setKey(char* _key);
  char* SetOrigStr(char*,int);
  char* SetCriptStr(char*,int);
  void CriptStr(char* _key);
  void decriptStr(char* _key);
  AnsiString getAnsiData();
  bool setAnsiData(AnsiString data);
};
//-----------------------------------------------------------------------
AnsiString A5Cripto::getAnsiData()
{
   AnsiString str="",ch;
   for(int i=0;i<len;i++){
     ch=IntToStr(((char)crStr[i])+127);
     while(ch.Length()<3)ch="0"+ch;
     str+=ch;
   }
   return str;
}
//-----------------------------------------------------------------------
bool A5Cripto::setAnsiData(AnsiString data)
{
   if(crStr)
     delete crStr;
   len=data.Length()/3;
   crStr=new char[len+1];
   AnsiString ch;
   for(int i=0;i<len;i++){
     ch=data.SubString(3*i+1,3);
     crStr[i]=(char)(StrToInt(ch)-127);
     ch="";
   }
   return true;
}
//-----------------------------------------------------------------------
void A5Cripto::move(char* from,char* to)
{
  for(int i=0;i<len;i++){
    to[i]=from[i];
  }
  to[len]='\0';
}
bool A5Cripto::setKey(char* _key){
   if(strlen(_key)<keyLen)
     return false;
   for(int i=0;i<keyLen;i++){
     key[i]=_key[i];
   }
   return true;
}
//-----------------------------------------------------------------------
char* A5Cripto::SetOrigStr(char* str,int _len){
   if(orStr)
     delete orStr;
   len=_len;
   orStr=new char[len+1];
   move(str,orStr);
   return orStr;
}
//-----------------------------------------------------------------------
char* A5Cripto::SetCriptStr(char* str,int _len){
   if(crStr)
     delete crStr;
   len=_len;
   crStr=new char[len+1];
   move(str,crStr);
   return crStr;
}
//-----------------------------------------------------------------------
void A5Cripto::CriptStr(char* _key)
{
  setKey(_key);
  char* tmp=new char[len+1];
  move(orStr,tmp);
  a5_key(&c,key);
  a5_encrypt(&c,tmp,len);
  SetCriptStr(tmp,len);
  delete tmp;
}
//-----------------------------------------------------------------------
void A5Cripto::decriptStr(char* _key)
{
  setKey(_key);
  char* tmp=new char[len+1];
  move(crStr,tmp);
  a5_key(&c,key);
  a5_decrypt(&c,tmp,1);
  a5_decrypt(&c,tmp+1,len-1);
  SetOrigStr(tmp,len);
  delete tmp;

}

//-----------------------------------------------------------------------
int A5Cripto::threshold(unsigned int r1, unsigned int r2, unsigned int r3)
{
	int total;
	total = (((r1 >> 9) & 0x1) == 1) 
	        + (((r2 >> 11) & 0x1) == 1) 
			+ (((r3 >> 11) & 0x1) == 1) ;
	if (total > 1)
		return (0) ;
	else
 		return (1) ;
}
//-----------------------------------------------------------------------
unsigned long A5Cripto::clock_r1(int ctl, unsigned long r1)
{
	unsigned long feedback;
	ctl ^= ( (r1 >> 9) & 0x1);
	if (ctl)
	{
		feedback = (r1 >> 18) ^ (r1 >> 17) ^ (r1 >> 16) ^ (r1 >> 13);
		r1 = (r1 << 1) & 0x7ffff;
		if (feedback & 0x01)
			r1 ^= 0x01;
	}
	return (r1);
}
//-----------------------------------------------------------------------
unsigned long A5Cripto::clock_r2(int ctl, unsigned long r2)
{
	unsigned long feedback;
	ctl ^= ( (r2 >> 11) & 0x1);
	if (ctl)
	{
		feedback = (r2 >> 21) ^ (r2 >> 20) ^ (r2 >> 16) ^ (r2 >> 12);
		r2 = (r2 << 1) & 0x3fffff;
		if (feedback & 0x01)
			r2 ^= 0x01; 
	}
	return (r2); 
}
//-----------------------------------------------------------------------
unsigned long A5Cripto::clock_r3(int ctl,unsigned long  r3)
{
	unsigned long feedback;
	ctl ^= ( (r3 >> 11) & 0x1);
	if (ctl)
	{
		feedback = (r3 >> 22) ^ (r3 >> 21) ^ (r3 >> 18) ^ (r3 >> 17);
		r3 = (r3 << 1) & 0x7fffff;
		if (feedback & 0x01)
		r3 ^= 0x01;
	}
	return (r3);
}
//-----------------------------------------------------------------------
int A5Cripto::keystream(
	unsigned char *key,   /* 64 bit session key	*/
	unsigned long frame,  /* 22 bit frame sequence number    */
	unsigned char *alice, /* 114 bit Alice to Bob key stream */
	unsigned char *bob)   /* 114 bit Bob to Alice key stream */
{
	unsigned long r1;   /* 19 bit shift register */
	unsigned long r2;   /* 22 bit shift register */

	/* 23 bit shift register */
	unsigned long r3; int i;
	int clock_ctl;
	unsigned char *ptr;
	unsigned char byte;
	unsigned int bits;
	unsigned int bit;
	/* counter for loops
	/*	xored with clock enable on each shift register */
	/*	current position in keystream */
	/*	byte of keystream being assembled */
	/*	number of bits of keystream in byte */
	/* bit output from keystream generator */ 
	/* Initialise shift registers from session key */
	r1 = (key[0] | (key[1] << 8) | (key[2] << 16)	) & 0x7ffff;
	r2 = ((key[2] >> 3) | (key[3] << 5) | (key[4]	<< 13) | (key[5] << 21)) & 0x3fffff;
	r3 = ((key[5] >> 1) | (key[6] << 7) | (key[7]	<< 15) ) & 0x7fffff;
 
	 Merge frame sequence number into shift register state, 
	// by xor'ing it * into the feedback path 
	for (i=0;i<22;i++) {
		clock_ctl = threshold(r1, r2,r2);
		r1 = clock_r1(clock_ctl,r1);
		r2 = clock_r2(clock_ctl,r2); 
		r3 = clock_r3(clock_ctl, r3);
		if (frame & 1) {
			r1 ^= 1;
			r2 ^= 1;
			r3 ^= 1; 
		}
		frame = frame >> 1;
	}
	// Run shift registers for 100 clock ticks to allow frame number to * be diffused 
	//  into all the bits of the shift registers 
	for (i=0;i<100;i++) {
		clock_ctl = threshold(r1, r2, r2);
		r1 = clock_r1(clock_ctl, r1);
		r2 = clock_r2(clock_ctl, r2);
		r3 = clock_r3(clock_ctl, r3); 
	}
	/* Produce 114 bits of Alice->Bob key stream */
	ptr = alice;
	bits = 0;
	byte = 0;
	for (i=0;i<114;i++)
	{
		clock_ctl = threshold(r1, r2 , r2);
		r1 = clock_r1(clock_ctl, r1);
		r2 = clock_r2(clock_ctl, r2);
		r3 = clock_r3(clock_ctl, r3);

		bit = ( (r1 >> 18) ^ (r2 >> 21) ^ (r3 >> 22)) & 0x01;
		byte = (byte << 1) | bit;
		bits++;

		if (bits == 8) {
			*ptr = byte; 
			ptr++; 
			bits = 0; 
			byte = 0; 
		} 
	} 
	if (bits)
		*ptr = byte;
	/* Run shift registers for another 100 bits to hide relationship between 
	 * Alice->Bob key stream and Bob->Alice key stream. 
	 */
 
	for (i=0;i<100;i++)
	{
		clock_ctl = threshold(r1, r2 ,r2);
		r1 = clock_r1(clock_ctl, r1) ;
		r2 = clock_r2(clock_ctl, r2) ;
		r3 = clock_r3(clock_ctl, r3);
	} 
 
	/* Produce 114 bits of Bob->Alice key stream */
	ptr = bob;
	bits = 0;
	byte = 0;
	for (i=0;i<114;i++)
	{
		clock_ctl = threshold(r1, r2 , r2);
		r1 = clock_r1(clock_ctl, r1);
		r2 = clock_r2(clock_ctl, r2);
		r3 = clock_r3(clock_ctl, r3);
 
		bit = ( (r1 >> 18)	^ (r2 >> 21) ^ (r3 >> 22)) & 0x01;
		byte = (byte << 1) | 	bit;
		bits++;
		if (bits == 8)
		{
			*ptr = byte;
			ptr++;
			bits = 0;
			byte = 0; 
		} 
	} 
	if (bits)
		*ptr = byte;
	return (0);
}
//-----------------------------------------------------------------------
void A5Cripto::a5_key(a5_ctx *c, char *k)
{
	c->r1 = k[0]<<11|k[1]<<3 | k[2]>>5;
	c->r2 = k[2]<<17|k[3]<<9 | k[4]<<1 | k[5]>>7;
	c->r3 = k[5]<<15|k[6]<<8 | k[7];
}
//-----------------------------------------------------------------------
int A5Cripto::a5_step(a5_ctx *c)
{
	int control;
 	control = threshold(c->r1,c->r2,c->r3);
	c->r1 = clock_r1(control,c->r1) ;/* 19 */
	c->r2 = clock_r2(control,c->r2) ;/* 22 */
	c->r3 = clock_r3(control,c->r3) ;/* 23 */
	return( (c->r1^c->r2^c->r3) &1);
}
//-----------------------------------------------------------------------
void A5Cripto::a5_encrypt(a5_ctx *c, char *data, int len)
{
	int i,j;
	char t;
	for(i=0;i<len;i++){
		for(j=0;j<8;j++) t = t<<1| a5_step(c);
			data[i]^=t;
	}
}
//-----------------------------------------------------------------------
void A5Cripto::a5_decrypt(a5_ctx *c, char *data, int len){
	a5_encrypt(c,data,len);
}
Разработано на основе учебника "Прикладная криптография 2-е издание" Брюс Шнайер. (поэтому в исходниках есть такие как Алиса и Боб - друзья разведчики :) ).
// криптование
AnsiString str="string to cript", pswd="encription key";
A5Cripto a5;
a5.SetOrigStr(str.c_str(),str.Length());
a5.CriptStr(pswd.c_str());
str=a5.getAnsiData(); 

// Расшифровка
A5Cripto a5;
a5.setAnsiData(str);
a5.decriptStr(pswd.c_str());
str=a5.getOrStr();
Rambler's Top100
Hosted by uCoz